﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using SSTestAPI;
using System.Xml;

namespace SoftServeTest
{
    public class CommonTasks
    {
        private ArrayList plantsList;   // список растений(деревьев и цветков)
        // свойство для получения/установления списка растений
        public ArrayList PlantsList 
        {
            get { return plantsList; }
            set { plantsList = value; }
        }
        // сортировка списка растений по убыванию
        public void sortPlantsList()    
        {
            plantsList.Sort(new PlantsComparer());
        }
        // конструктор
        public CommonTasks()    
        {
            plantsList = new ArrayList();
        }
        // сохранение в файл
        public void SaveToFile(string filepath, FileMode fm)    
        {
            Stream stream = File.Open(filepath, fm);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(stream, PlantsList);
            stream.Close();
        }
        // чтение из файла
        public void OpenFromFile(string filepath, FileMode fm)  
        {
            Stream stream = File.Open(filepath, fm);
            BinaryFormatter bf = new BinaryFormatter();
            try
            {
                PlantsList = (ArrayList)bf.Deserialize(stream);
            }
            catch (Exception e)
            {
                throw new OwnException("Check file format. ", e);
            }
            stream.Close();
            if (stream != null) stream = null;
            if (bf != null) bf = null; 
        }
        public void SaveToXML(string filepath)
        {
            if (plantsList == null || plantsList.Count == 0) return;
            XmlTextWriter xmlWriter = new XmlTextWriter(filepath, Encoding.Unicode);
            xmlWriter.WriteStartDocument();
            xmlWriter.WriteStartElement("Plants");
            foreach (object ob in plantsList)
            {
                xmlWriter.WriteStartElement("Plant");
                if (ob is Tree)
                {
                    xmlWriter.WriteAttributeString("PlantType", "Tree");
                    xmlWriter.WriteAttributeString("TreeBranch", ((Tree) ob).Branch);
                    xmlWriter.WriteAttributeString("TreeGroup", ((Tree)ob).Group);
                    xmlWriter.WriteAttributeString("TreeFruit", ((Tree)ob).Fruit.ToString());
                    xmlWriter.WriteAttributeString("TreeLifetime", ((Tree)ob).getLifetime().ToString());
                }
                else if (ob is Flower)
                {
                    xmlWriter.WriteAttributeString("PlantType", "Flower");
                    xmlWriter.WriteAttributeString("FlowerBranch", ((Flower)ob).Branch);
                    xmlWriter.WriteAttributeString("FlowerSymmetric", ((Flower)ob).Symmetric.ToString());
                    xmlWriter.WriteAttributeString("FlowerLeafs", ((Flower)ob).LeafsQuantity.ToString());
                    xmlWriter.WriteAttributeString("FlowerLifetime", ((Flower)ob).getLifetime().ToString());
                }
                xmlWriter.WriteEndElement();
            }
            xmlWriter.WriteEndElement();
            xmlWriter.WriteEndDocument();
            xmlWriter.Close();
            if (xmlWriter != null) xmlWriter = null;
        }
        public void OpenFromXML(string filepath)
        {
            if (plantsList != null) plantsList.Clear();
            else plantsList = new ArrayList();
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(filepath);
            XmlNodeList xmlNodeList = xmlDoc.DocumentElement.ChildNodes;
            foreach (XmlNode xn in xmlNodeList)
            {
                switch (xn.Attributes.GetNamedItem("PlantType").Value)
                {
                    case "Flower":
                    {
                        plantsList.Add(new Flower(xn.Attributes.GetNamedItem("FlowerBranch").Value,
                            Boolean.Parse(xn.Attributes.GetNamedItem("FlowerSymmetric").Value),
                            Int32.Parse(xn.Attributes.GetNamedItem("FlowerLeafs").Value),
                            Int32.Parse(xn.Attributes.GetNamedItem("FlowerLifetime").Value)));
                        break;
                    }
                    case "Tree":
                    {
                        plantsList.Add(new Tree(xn.Attributes.GetNamedItem("TreeBranch").Value,
                            xn.Attributes.GetNamedItem("TreeGroup").Value,
                            Boolean.Parse(xn.Attributes.GetNamedItem("TreeFruit").Value),
                            Int32.Parse(xn.Attributes.GetNamedItem("TreeLifetime").Value)));
                        break;
                    }
                    default:
                        break;
                }
            }
            if (xmlNodeList != null) xmlNodeList = null;
            if (xmlDoc != null) xmlDoc = null;
        }
        public void SaveToCSV(string filepath)
        {
            if (plantsList == null || plantsList.Count == 0) return;
            using (StreamWriter sr = new StreamWriter(filepath, false, Encoding.Unicode))
            {
                string header = "PlantType;Branch;Lifetime;TreeGroup;TreeFruit;FlowerSymmetric;FlowerLeafs";
                string row;
                sr.WriteLine(header);
                foreach (object ob in plantsList)
	            {
                    if (ob is Tree)
                    {
                        row = "Tree;" +
                            ((Tree)ob).Branch + ";" +
                            ((Tree)ob).getLifetime() + ";" +
                            ((Tree)ob).Group + ";" +
                            ((Tree)ob).Fruit + ";;";
                        sr.WriteLine(row);
                    }
                    else if (ob is Flower)
                    {
                        row = "Flower;" +
                            ((Flower)ob).Branch + ";" +
                            ((Flower)ob).getLifetime() + ";" +
                            ";;" +
                            ((Flower)ob).Symmetric + ";" +
                            ((Flower)ob).LeafsQuantity;
                        sr.WriteLine(row);
                    }
	            }
            }
        }
        public void OpenFromCSV(string filepath)
        {
            if (plantsList != null) plantsList.Clear();
            else plantsList = new ArrayList();
            using (StreamReader sr = new StreamReader(filepath))
            {
                string line;
                string[] row;
                sr.ReadLine();
                while ((line = sr.ReadLine()) != null)
                {
                    row = line.Split(';');
                    switch (row[0])
                    {
                        case "Tree":
                            {
                                plantsList.Add(new Tree(row[1], row[3], Boolean.Parse(row[4]), Int32.Parse(row[2])));
                                break;
                            }
                        case "Flower":
                            {
                                plantsList.Add(new Flower(row[1], Boolean.Parse(row[5]), Int32.Parse(row[6]), Int32.Parse(row[2])));
                                break;
                            }
                        default:
                            break;
                    }
                }
            }
        }
    }
}
